package cyce.peer.filechooser;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.*;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.*;

import cyce.file.*;
import cyce.peer.Peer;

/**
 * This provides a representation of the distributed file system used 
 * in the GUI
 * @author CYCE
 *
 */
public class FileModel {
	
	private FileTreeModel treeModel;
	private Peer peer;
	
	public FileModel(Peer peer) {
		this.treeModel = new FileTreeModel();
		this.peer = peer;
		peer.setTreeModel(treeModel);
	}
	
	public FileTreeModel getTreeModel() {
		return this.treeModel;
	}
	
	public void saveFile(File file, String savePath) throws RemoteException, IOException {
		// TODO: test
		this.peer.getFileFromPeers(file, savePath);
		
	}
	
	public void uploadFile(String localPath, String uploadPath, String uploadName) throws Exception {
		this.peer.addFileToNetwork(localPath, uploadPath, uploadName);
	}
	
	public void addDirectory(String uploadPath, String dirName) throws Exception {
		this.peer.addDirectoryToNetwork(uploadPath, dirName);
	}
	
	public void deleteFile(File file) throws RemoteException {
		this.peer.removeFileFromNetwork(file);
	}
	
	public void deleteDirectory(Directory dir) throws RemoteException {
		this.peer.removeDirectoryFromNetwork(dir);
	}
	
	public boolean validateUploadName(String uploadName) {
		if (uploadName == null) return false;
		if (uploadName.equals("")) return false;
		return true;
	}
	
	public boolean validateDirectoryName(String dirName) {
		if (dirName == null) return false;
		if (dirName.equals("")) return false;
		return true;
	}
	
	public class FileTreeModel implements TreeModel {
		private ArrayList<TreeModelListener> listeners;
		
		public FileTreeModel() {
			this.listeners = new ArrayList<TreeModelListener>();
		}
		
		public void addTreeModelListener(TreeModelListener listener) {
			this.listeners.add(listener);
		}

		public Object getChild(Object file, int index) {
			if (file instanceof Directory)
				return ((Directory)file).getChildAt(index);
			else
				return null;
		}

		public int getChildCount(Object file) {
			if (file instanceof Directory)
				return ((Directory)file).getChildCount();
			else
				return 0;
		}

		public int getIndexOfChild(Object directory, Object file) {
			if (file instanceof Directory)
				return ((Directory)directory).getIndex((File)file);
			else
				return -1;
		}

		public Object getRoot() {
			return FileModel.this.peer.getRoot();
		}

		public boolean isLeaf(Object file) {
			return (!(file instanceof Directory));
		}

		public void removeTreeModelListener(TreeModelListener listener) {
			this.listeners.remove(listener);
		}

		public void valueForPathChanged(TreePath path, Object file) {
			// this shouldn't ever get called
			assert false;
		}
		
		public void updateTree(){
			TreeModelEvent e = new TreeModelEvent(this,new Object[]{ this.getRoot() });
			for (TreeModelListener listener : listeners){
				listener.treeStructureChanged(e);
			}
		}
	}
}
